home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
Pakiet bezpieczenstwa
/
mini Pentoo LiveCD 2006.1
/
mpentoo-2006.1.iso
/
livecd.squashfs
/
usr
/
lib
/
python2.4
/
site-packages
/
impacket
/
dcerpc
/
samr.py
< prev
next >
Wrap
Text File
|
2006-05-23
|
24KB
|
724 lines
# Copyright (c) 2003-2006 CORE Security Technologies
#
# This software is provided under under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
# for more information.
#
# $Id: samr.py,v 1.7 2006/05/23 21:19:26 gera Exp $
#
# Description:
# SAMR (Security Account Manager Remote) interface implementation.
#
import array
from time import strftime, gmtime
from struct import *
from impacket import ImpactPacket
import dcerpc
import ndrutils
MSRPC_UUID_SAMR = '\x78\x57\x34\x12\x34\x12\xcd\xab\xef\x00\x01\x23\x45\x67\x89\xac\x01\x00\x00\x00'
OP_NUM_CREATE_USER_IN_DOMAIN = 0xC
OP_NUM_ENUM_USERS_IN_DOMAIN = 0xD
OP_NUM_CREATE_ALIAS_IN_DOMAIN = 0xE
def display_time(filetime_high, filetime_low, minutes_utc=0):
d = filetime_high*4.0*1.0*(1<<30)
d += filetime_low
d *= 1.0e-7
d -= (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
if minutes_utc == 0:
r = (strftime("%a, %d %b %Y %H:%M:%S",gmtime(d)), minutes_utc/60)[0]
else:
r = "%s GMT %d " % (strftime("%a, %d %b %Y %H:%M:%S",gmtime(d)), minutes_utc/60)
return r
class MSRPCUserInfo:
ITEMS = {'Account Name':0,
'Full Name':1,
'Home':2,
'Home Drive':3,
'Script':4,
'Profile':5,
'Description':6,
'Workstations':7,
'Comment':8,
'Parameters':9,
'Logon hours':10
}
def __init__(self, data = None):
self._logon_time_low = 0
self._logon_time_high = 0
self._logoff_time_low = 0
self._logoff_time_high = 0
self._kickoff_time_low = 0
self._kickoff_time_high = 0
self._pwd_last_set_low = 0
self._pwd_last_set_high = 0
self._pwd_can_change_low = 0
self._pwd_can_change_high = 0
self._pwd_must_change_low = 0
self._pwd_must_change_high = 0
self._items = []
self._rid = 0
self._group = 0
self._acct_ctrl = 0
self._bad_pwd_count = 0
self._logon_count = 0
self._country = 0
self._codepage = 0
self._nt_pwd_set = 0
self._lm_pwd_set = 0
if data: self.set_header(data)
def set_header(self,data):
index = 8
self._logon_time_low, self._logon_time_high, self._logoff_time_low, self._logoff_time_high, self._kickoff_time_low,self._kickoff_time_high, self._pwd_last_set_low,self._pwd_last_set_high, self._pwd_can_change_low,self._pwd_can_change_high, self._pwd_must_change_low, self._pwd_must_change_high = unpack('<LLLLLLLLLLLL',data[index:index+48])
index += 48
for i in range(0,len(MSRPCUserInfo.ITEMS)-1):
length, size, id = unpack('<HHL',data[index:index+8])
self._items.append(dcerpc.MSRPCArray(length, size, id))
index += 8
index += 24 # salteo los unknowns
item_count = unpack('<L',data[index:index+4])[0]
index += 4 + (item_count+1) * 4 # Esto no lo se!! salteo buffer
self._rid, self._group, self._acct_ctr,_ = unpack('<LLLL',data[index: index+16])
index += 16
logon_divisions, _, id = unpack('<HHL',data[index:index+8])
self._items.append(dcerpc.MSRPCArray(logon_divisions, _, id))
index += 8
self._bad_pwd_count, self._logon_count, self._country, self._codepage = unpack('<HHHH', data[index: index + 8])
index += 8
self._nt_pwd_set, self._lm_pwd_set,_,_= unpack('<BBBB', data[index:index+4])
index += 4
for item in self._items[:-1]: # Except LOGON_HOUNS
if 0 == item.get_size():
continue
max_len, offset, curlen = unpack('<LLL', data[index:index+12])
index += 12
item.set_name(unicode(data[index:index+2*curlen], 'utf-16le'))
item.set_max_len(max_len)
item.set_offset(offset)
item.set_length2(curlen)
index += 2*curlen
if curlen & 0x1: index += 2 # Skip padding.
# Process LOGON_HOURS.
# This is a bitmask of logon_divisions bits. Normally logon_divisions is 168, one bit per hour of a whole week.
item = self._items[10]
max_len, offset, curlen = unpack('<LLL', data[index:index+12])
index += 12
item.set_name('Unlimited')
# I admit this routine is not very clever. We could do a better mapping to human readable format.
for b in data[index: index+curlen]:
if 0xFF != ord(b):
item.set_name('Unknown')
def get_num_items(self):
return len(self._items)
def get_items(self):
return self._items
def get_logon_time(self):
return display_time(self._logon_time_high, self._logon_time_low)
def get_logoff_time(self):
return display_time(self._logoff_time_high, self._logoff_time_low)
def get_kickoff_time(self):
return display_time(self._kickoff_time_high, self._kickoff_time_low)
def get_pwd_last_set(self):
return display_time(self._pwd_last_set_high, self._pwd_last_set_low)
def get_pwd_can_change(self):
return display_time(self._pwd_can_change_high, self._pwd_can_change_low)
def get_group_id(self):
return self._group
def get_bad_pwd_count(self):
return self._bad_pwd_count
def get_logon_count(self):
return self._logon_count
def get_pwd_must_change(self):
if self._pwd_must_change_low == 4294967295L:
return "Infinity"
else:
return display_time(self._pwd_must_change_high, self._pwd_must_change_low)
def is_enabled(self):
return not (self._acct_ctr & 0x01)
def print_friendly(self):
print "Last Logon: " + display_time(self._logon_time_high, self._logon_time_low)
print "Last Logoff: " + display_time(self._logoff_time_high, self._logoff_time_low)
print "Kickoff Time: " + display_time(self._kickoff_time_high, self._kickoff_time_low)
print "PWD Last Set: " + display_time(self._pwd_last_set_high, self._pwd_last_set_low)
print "PWD Can Change: " + display_time(self._pwd_can_change_high, self._pwd_can_change_low)
print "Group id: %d" % self._group
print "Bad pwd count: %d" % self._bad_pwd_count
print "Logon count: %d" % self._logon_count
if self._pwd_must_change_low == 4294967295L:
print "PWD Must Change: Infinity"
else:
print "PWD Must Change: " + display_time(self._pwd_must_change_high, self._pwd_must_change_low)
for i in MSRPCUserInfo.ITEMS.keys():
print i + ': ' + self._items[MSRPCUserInfo.ITEMS[i]].get_name()
print
return
class SAMRConnectHeader(ImpactPacket.Header):
OP_NUM = 0x39
__SIZE = 4
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMRConnectHeader.__SIZE)
self.__sptr = ndrutils.NDRPointer()
self.set_server('')
self.set_access_mask(0x2000000)
if aBuffer: self.load_header(aBuffer)
def get_server(self):
return ndrutils.NDRPointer(self.get_bytes()[:-4].tostring(), ndrutils.NDRString)
def set_server(self, name):
ss = ndrutils.NDRString()
ss.set_string(name)
self.__sptr.set_pointer(ss)
data = self.__sptr.rawData()
self.get_bytes()[:-4] = array.array('B', data)
def get_access_mask(self):
return self.get_long(-4, '<')
def set_access_mask(self, mask):
self.set_long(-4, mask, '<')
def get_header_size(self):
var_size = len(self.get_bytes()) - SAMRConnectHeader.__SIZE
assert var_size > 0
return SAMRConnectHeader.__SIZE + var_size
class SAMRRespConnectHeader(ImpactPacket.Header):
__SIZE = 24
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMRRespConnectHeader.__SIZE)
if aBuffer: self.load_header(aBuffer)
def get_context_handle(self):
return self.get_bytes().tostring()[:20]
def set_context_handle(self, handle):
assert 20 == len(handle)
self.get_bytes()[:20] = array.array('B', handle)
def get_return_code(self):
return self.get_long(20, '<')
def set_return_code(self, code):
self.set_long(20, code, '<')
def get_header_size(self):
return SAMRRespConnectHeader.__SIZE
class SAMREnumDomainsHeader(ImpactPacket.Header):
OP_NUM = 0x6
__SIZE = 28
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMREnumDomainsHeader.__SIZE)
self.set_pref_max_size(8192)
if aBuffer: self.load_header(aBuffer)
def get_context_handle(self):
return self.get_bytes().tolist()[:20]
def set_context_handle(self, handle):
assert 20 == len(handle)
self.get_bytes()[:20] = array.array('B', handle)
def get_resume_handle(self):
return self.get_long(20, '<')
def set_resume_handle(self, handle):
self.set_long(20, handle, '<')
def get_pref_max_size(self):
return self.get_long(24, '<')
def set_pref_max_size(self, size):
self.set_long(24, size, '<')
def get_header_size(self):
return SAMREnumDomainsHeader.__SIZE
class SAMRRespEnumDomainHeader(ImpactPacket.Header):
__SIZE = 12
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMRRespEnumDomainHeader.__SIZE)
if aBuffer: self.load_header(aBuffer)
def get_resume_handle(self):
return self.get_long(0, '<')
def set_resume_handle(self, handle):
self.set_long(0, handle, '<')
def get_domains(self):
return dcerpc.MSRPCNameArray(self.get_bytes()[4:-8].tostring())
def set_domains(self, domains):
assert isinstance(domains, dcerpc.MSRPCNameArray)
self.get_bytes()[4:-8] = array.array('B', domains.rawData())
def get_entries_num(self):
return self.get_long(-8, '<')
def set_entries_num(self, num):
self.set_long(-8, num, '<')
def get_return_code(self):
return self.get_long(-4, '<')
def set_return_code(self, code):
self.set_long(-4, code, '<')
def get_header_size(self):
var_size = len(self.get_bytes()) - SAMRRespEnumDomainHeader.__SIZE
assert var_size > 0
return SAMRRespEnumDomainHeader.__SIZE + var_size
class SAMRLookupDomainHeader(ImpactPacket.Header):
OP_NUM = 0x5
__SIZE = 20
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMRLookupDomainHeader.__SIZE)
if aBuffer: self.load_header(aBuffer)
def get_context_handle(self):
return self.get_bytes().tolist()[:20]
def set_context_handle(self, handle):
assert 20 == len(handle)
self.get_bytes()[:20] = array.array('B', handle)
def get_domain(self):
return dcerpc.MSRPCArray(self.get_bytes().tolist()[20:])
def set_domain(self, domain):
assert isinstance(domain, dcerpc.MSRPCArray)
self.get_bytes()[20:] = array.array('B', domain.rawData())
def get_header_size(self):
var_size = len(self.get_bytes()) - SAMRLookupDomainHeader.__SIZE
assert var_size > 0
return SAMRLookupDomainHeader.__SIZE + var_size
class SAMRRespLookupDomainHeader(ImpactPacket.Header):
__SIZE = 36
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMRRespLookupDomainHeader.__SIZE)
if aBuffer: self.load_header(aBuffer)
## def get_sid_count(self):
## return self.get_long(4, '<')
## def set_sid_count(self, count):
## self.set_long(4, count, '<')
## def get_domain_sid(self):
## return self.get_bytes().tolist()[8:8+24]
## def set_domain_sid(self, sid):
## assert 24 == len(sid)
## self.get_bytes()[8:8+24] = array.array('B', sid)
def get_domain_sid(self):
return self.get_bytes().tolist()[4:4+28]
def set_domain_sid(self, sid):
assert 28 == len(sid)
self.get_bytes()[4:4+28] = array.array('B', sid)
def get_return_code(self):
return self.get_long(32, '<')
def set_return_code(self, code):
self.set_long(32, code, '<')
def get_header_size(self):
return SAMRRespLookupDomainHeader.__SIZE
class SAMROpenDomainHeader(ImpactPacket.Header):
OP_NUM = 0x7
__SIZE = 52
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMROpenDomainHeader.__SIZE)
self.set_access_mask(0x304)
if aBuffer: self.load_header(aBuffer)
def get_context_handle(self):
return self.get_bytes().tolist()[:20]
def set_context_handle(self, handle):
assert 20 == len(handle)
self.get_bytes()[:20] = array.array('B', handle)
def get_access_mask(self):
return self.get_long(20, '<')
def set_access_mask(self, mask):
self.set_long(20, mask, '<')
## def get_sid_count(self):
## return self.get_long(24, '<')
## def set_sid_count(self, count):
## self.set_long(24, count, '<')
## def get_domain_sid(self):
## return self.get_bytes().tolist()[28:28+24]
## def set_domain_sid(self, sid):
## assert 24 == len(sid)
## self.get_bytes()[28:28+24] = array.array('B', sid)
def get_domain_sid(self):
return self.get_bytes().tolist()[24:24+28]
def set_domain_sid(self, sid):
assert 28 == len(sid)
self.get_bytes()[24:24+28] = array.array('B', sid)
def get_header_size(self):
return SAMROpenDomainHeader.__SIZE
class SAMRRespOpenDomainHeader(ImpactPacket.Header):
__SIZE = 24
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMRRespOpenDomainHeader.__SIZE)
if aBuffer: self.load_header(aBuffer)
def get_context_handle(self):
return self.get_bytes().tolist()[:20]
def set_context_handle(self, handle):
assert 20 == len(handle)
self.get_bytes()[:20] = array.array('B', handle)
def get_return_code(self):
return self.get_long(20, '<')
def set_return_code(self, code):
self.set_long(20, code, '<')
def get_header_size(self):
return SAMRRespOpenDomainHeader.__SIZE
class SAMREnumDomainUsersHeader(ImpactPacket.Header):
OP_NUM = OP_NUM_ENUM_USERS_IN_DOMAIN
__SIZE = 32
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMREnumDomainUsersHeader.__SIZE)
self.set_pref_max_size(3275)
if aBuffer: self.load_header(aBuffer)
def get_context_handle(self):
return self.get_bytes().tolist()[:20]
def set_context_handle(self, handle):
assert 20 == len(handle)
self.get_bytes()[:20] = array.array('B', handle)
def get_resume_handle(self):
return self.get_long(20, '<')
def set_resume_handle(self, handle):
self.set_long(20, handle, '<')
def get_account_control(self):
return self.get_long(24, '<')
def set_account_control(self, mask):
self.set_long(24, mask, '<')
def get_pref_max_size(self):
return self.get_long(28, '<')
def set_pref_max_size(self, size):
self.set_long(28, size, '<')
def get_header_size(self):
return SAMREnumDomainUsersHeader.__SIZE
class SAMRRespEnumDomainUsersHeader(ImpactPacket.Header):
__SIZE = 16
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMRRespEnumDomainUsersHeader.__SIZE)
if aBuffer: self.load_header(aBuffer)
def get_resume_handle(self):
return self.get_long(0, '<')
def set_resume_handle(self, handle):
self.set_long(0, handle, '<')
def get_users(self):
return dcerpc.MSRPCNameArray(self.get_bytes()[4:-8].tostring())
def set_users(self, users):
assert isinstance(users, dcerpc.MSRPCNameArray)
self.get_bytes()[4:-8] = array.array('B', users.rawData())
def get_entries_num(self):
return self.get_long(-8, '<')
def set_entries_num(self, num):
self.set_long(-8, num, '<')
def get_return_code(self):
return self.get_long(-4, '<')
def set_return_code(self, code):
self.set_long(-4, code, '<')
def get_header_size(self):
var_size = len(self.get_bytes()) - SAMRRespEnumDomainUsersHeader.__SIZE
assert var_size > 0
return SAMRRespEnumDomainUsersHeader.__SIZE + var_size
class SAMROpenUserHeader(ImpactPacket.Header):
OP_NUM = 0x22
__SIZE = 28
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMROpenUserHeader.__SIZE)
self.set_access_mask(0x2011B)
if aBuffer: self.load_header(aBuffer)
def get_context_handle(self):
return self.get_bytes().tolist()[:20]
def set_context_handle(self, handle):
assert 20 == len(handle)
self.get_bytes()[:20] = array.array('B', handle)
def get_access_mask(self):
return self.get_long(20, '<')
def set_access_mask(self, mask):
self.set_long(20, mask, '<')
def get_rid(self):
return self.get_long(24, '<')
def set_rid(self, id):
self.set_long(24, id, '<')
def get_header_size(self):
return SAMROpenUserHeader.__SIZE
class SAMRRespOpenUserHeader(ImpactPacket.Header):
__SIZE = 24
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMRRespOpenUserHeader.__SIZE)
if aBuffer: self.load_header(aBuffer)
def get_context_handle(self):
return self.get_bytes().tolist()[:20]
def set_context_handle(self, handle):
assert 20 == len(handle)
self.get_bytes()[:20] = array.array('B', handle)
def get_return_code(self):
return self.get_long(20, '<')
def set_return_code(self, code):
self.set_long(20, code, '<')
def get_header_size(self):
return SAMRRespOpenUserHeader.__SIZE
class SAMRQueryUserInfoHeader(ImpactPacket.Header):
OP_NUM = 0x24
__SIZE = 22
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMRQueryUserInfoHeader.__SIZE)
self.set_level(21)
if aBuffer: self.load_header(aBuffer)
def get_context_handle(self):
return self.get_bytes().tolist()[:20]
def set_context_handle(self, handle):
assert 20 == len(handle)
self.get_bytes()[:20] = array.array('B', handle)
def get_level(self):
return self.get_word(20, '<')
def set_level(self, level):
self.set_word(20, level, '<')
def get_header_size(self):
return SAMRQueryUserInfoHeader.__SIZE
class SAMRRespQueryUserInfoHeader(ImpactPacket.Header):
__SIZE = 4
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMRRespQueryUserInfoHeader.__SIZE)
if aBuffer: self.load_header(aBuffer)
def get_user_info(self):
return MSRPCUserInfo(self.get_bytes()[:-4].tostring())
def set_user_info(self, info):
assert isinstance(info, MSRPCUserInfo)
self.get_bytes()[:-4] = array.array('B', info.rawData())
def get_return_code(self):
return self.get_long(-4, '<')
def set_return_code(self, code):
self.set_long(-4, code, '<')
def get_header_size(self):
var_size = len(self.get_bytes()) - SAMRRespQueryUserInfoHeader.__SIZE
assert var_size > 0
return SAMRRespQueryUserInfoHeader.__SIZE + var_size
class SAMRCloseRequestHeader(ImpactPacket.Header):
OP_NUM = 0x1
__SIZE = 20
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMRCloseRequestHeader.__SIZE)
if aBuffer: self.load_header(aBuffer)
def get_context_handle(self):
return self.get_bytes().tolist()[:20]
def set_context_handle(self, handle):
assert 20 == len(handle)
self.get_bytes()[:20] = array.array('B', handle)
def get_header_size(self):
return SAMRCloseRequestHeader.__SIZE
class SAMRRespCloseRequestHeader(ImpactPacket.Header):
__SIZE = 24
def __init__(self, aBuffer = None):
ImpactPacket.Header.__init__(self, SAMRRespCloseRequestHeader.__SIZE)
if aBuffer: self.load_header(aBuffer)
def get_context_handle(self):
return self.get_bytes().tolist()[:20]
def set_context_handle(self, handle):
assert 20 == len(handle)
self.get_bytes()[:20] = array.array('B', handle)
def get_return_code(self):
return self.get_long(20, '<')
def set_return_code(self, code):
self.set_long(20, code, '<')
def get_header_size(self):
return SAMRRespCloseRequestHeader.__SIZE
class DCERPCSamr:
def __init__(self, dcerpc):
self._dcerpc = dcerpc
def connect(self):
samrcon = SAMRConnectHeader()
samrcon.set_server('*SMBSERVER')
self._dcerpc.send(samrcon)
data = self._dcerpc.recv()
retVal = SAMRRespConnectHeader(data)
return retVal
def enumdomains(self,context_handle):
enumdom = SAMREnumDomainsHeader()
enumdom.set_context_handle(context_handle)
self._dcerpc.send(enumdom)
data = self._dcerpc.recv()
retVal = SAMRRespEnumDomainHeader(data)
return retVal
def lookupdomain(self,context_handle,domain):
lookupdom = SAMRLookupDomainHeader()
lookupdom.set_context_handle(context_handle)
lookupdom.set_domain(domain)
self._dcerpc.send(lookupdom)
data = self._dcerpc.recv()
retVal = SAMRRespLookupDomainHeader(data)
return retVal
def opendomain(self,context_handle,domain_sid):
opendom = SAMROpenDomainHeader()
opendom.set_context_handle(context_handle)
opendom.set_domain_sid(domain_sid)
self._dcerpc.send(opendom)
data = self._dcerpc.recv()
retVal = SAMRRespOpenDomainHeader(data)
return retVal
def enumusers(self,context_handle):
enumusers = SAMREnumDomainUsersHeader()
enumusers.set_context_handle(context_handle)
self._dcerpc.send(enumusers)
data = self._dcerpc.recv()
retVal = SAMRRespEnumDomainUsersHeader(data)
return retVal
def openuser(self,context_handle, rid):
openuser = SAMROpenUserHeader()
openuser.set_context_handle(context_handle)
openuser.set_rid(rid)
self._dcerpc.send(openuser)
data = self._dcerpc.recv()
retVal = SAMRRespOpenUserHeader(data)
return retVal
def queryuserinfo(self,context_handle):
userinfo = SAMRQueryUserInfoHeader()
userinfo.set_context_handle(context_handle)
self._dcerpc.send(userinfo)
data = self._dcerpc.recv()
retVal = SAMRRespQueryUserInfoHeader(data)
return retVal
def closerequest(self,context_handle):
closereq = SAMRCloseRequestHeader()
closereq.set_context_handle(context_handle)
self._dcerpc.send(closereq)
data = self._dcerpc.recv()
retVal = SAMRRespCloseRequestHeader(data)
return retVal